import 'dart:async';
import 'dart:math';
import 'dart:math' as math;
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bilibili/core/extension/int_extension.dart';
import 'package:flutter_bilibili/core/service/utils/json_parse.dart';
import 'package:flutter_bilibili/ui/shared/app_theme.dart';
import 'package:flutter_svg/svg.dart';
import 'dart:ui' as ui;
import '../../../../core/model/big_data_model.dart';

class HYLineChartSamples extends StatefulWidget {
  const HYLineChartSamples({Key? key}) : super(key: key);

  @override
  State<HYLineChartSamples> createState() => _HYLineChartSamplesState();
}

class _HYLineChartSamplesState extends State<HYLineChartSamples> {
  List<Range> _opusCountRange = [];
  List<Range> _opusCountRange02 = [];

  @override
  void initState() {
    super.initState();
    HYJsonParse.getBigData().then((value) {
      setState(() {
        _opusCountRange = value.lastMonthOpus.opusCountRange;
      });
    });
    HYJsonParse.getBigData02().then((value) {
      setState(() {
        _opusCountRange02 = value.lastMonthOpus.opusCountRange;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Theme.of(context).canvasColor,
      child: ListView(
        children: [
          Padding(
            padding: const EdgeInsets.only(
              left: 28,
              right: 28,
            ),
            child: buildLineChartSample01(),
          ),
          SizedBox(
            height: 8.px,
          ),
          Padding(
            padding: const EdgeInsets.only(
              left: 28,
              right: 28,
            ),
            child: buildLineChartSample02(),
          ),
          SizedBox(
            height: 8.px,
          ),
          Padding(
            padding: const EdgeInsets.only(
              left: 28,
              right: 28,
            ),
            child: buildLineChartSample03(),
          ),
          SizedBox(
            height: 8.px,
          ),
          Padding(
            padding: const EdgeInsets.only(
              left: 28,
              right: 28,
            ),
            child: buildLineChartSample04(),
          ),
          SizedBox(
            height: 8.px,
          ),
          Padding(
            padding: const EdgeInsets.only(
              left: 28,
              right: 28,
            ),
            child: buildLineChartSample05(),
          ),
          SizedBox(
            height: 8.px,
          ),
          Padding(
            padding: const EdgeInsets.only(
              left: 28,
              right: 28,
            ),
            child: buildLineChartSample06(),
          ),
          SizedBox(
            height: 8.px,
          ),
          Padding(
            padding: const EdgeInsets.only(
              left: 28,
              right: 28,
            ),
            child: buildLineChartSample07(),
          ),
          SizedBox(
            height: 8.px,
          ),
          Padding(
            padding: const EdgeInsets.only(
              left: 28,
              right: 28,
            ),
            child: BuildLineChartSample08(),
          ),
          SizedBox(
            height: 8.px,
          ),
          Padding(
            padding: const EdgeInsets.only(
              left: 28,
              right: 28,
            ),
            child: BuildLineChartSample9(),
          ),
          SizedBox(
            height: 8.px,
          ),
          Padding(
            padding: const EdgeInsets.only(
              left: 28,
              right: 28,
            ),
            child: BuildLineChartSample10(),
          ),
        ],
      ),
    );
  }

  List<FlSpot> getFlSpotList() {
    List<FlSpot> flSpotList = [];
    for (double i = 0; i < 25; i++) {
      double x = i + 1;
      double y = _opusCountRange[i.toInt()].percent2Double;
      flSpotList.add(FlSpot(x, y));
    }
    return flSpotList;
  }

  List<FlSpot> getFlSpotList02() {
    List<FlSpot> flSpotList = [];
    for (double i = 0; i < 25; i++) {
      double x = i + 1;
      double y = _opusCountRange02[i.toInt()].percent2Double;
      flSpotList.add(FlSpot(x, y));
    }
    return flSpotList;
  }

  /// Lerps between a [LinearGradient] colors, based on [t]
  Color lerpGradient(List<Color> colors, List<double> stops, double t) {
    if (colors.isEmpty) {
      throw ArgumentError('"colors" is empty.');
    } else if (colors.length == 1) {
      return colors[0];
    }

    if (stops.length != colors.length) {
      stops = [];

      /// provided gradientColorStops is invalid and we calculate it here
      colors.asMap().forEach((index, color) {
        final percent = 1.0 / (colors.length - 1);
        stops.add(percent * index);
      });
    }

    for (var s = 0; s < stops.length - 1; s++) {
      final leftStop = stops[s], rightStop = stops[s + 1];
      final leftColor = colors[s], rightColor = colors[s + 1];
      if (t <= leftStop) {
        return leftColor;
      } else if (t < rightStop) {
        final sectionT = (t - leftStop) / (rightStop - leftStop);
        return Color.lerp(leftColor, rightColor, sectionT)!;
      }
    }
    return colors.last;
  }

  Widget buildLineChartSample01() {
    return AspectRatio(
      aspectRatio: 1.23,
      child: Container(
        decoration: const BoxDecoration(
          borderRadius: BorderRadius.all(Radius.circular(10)),
          gradient: LinearGradient(
            colors: [
              Color(0x77ef96c5),
              Color(0x77ccfbff),
            ],
            begin: Alignment.bottomCenter,
            end: Alignment.topCenter,
          ),
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            SizedBox(
              height: 37.px,
            ),
            Text(
              '近30日投稿UP主趋势',
              style: TextStyle(
                color: HYAppTheme.norTextColors,
                fontSize: 16.px,
              ),
              textAlign: TextAlign.center,
            ),
            SizedBox(
              height: 4.px,
            ),
            Text(
              '趋势图 (1)',
              style: TextStyle(
                color: Colors.black,
                fontSize: HYAppTheme.smallFontSize,
                fontWeight: FontWeight.bold,
                letterSpacing: 2,
              ),
              textAlign: TextAlign.center,
            ),
            SizedBox(
              height: 37.px,
            ),
            Expanded(
              child: Padding(
                padding: EdgeInsets.only(right: 16.px, left: 6.px),
                child: buildLineChart01(),
              ),
            ),
            SizedBox(
              height: 10.px,
            ),
          ],
        ),
      ),
    );
  }

  Widget buildLineChart01() {
    return LineChart(
      LineChartData(
        minX: 0,
        maxX: _opusCountRange.length.toDouble(),
        maxY: 10,
        minY: 0,
        borderData: FlBorderData(
          show: true,
          border: const Border(
            bottom: BorderSide(color: HYAppTheme.norGrayColor, width: 1),
            left: BorderSide(color: HYAppTheme.norGrayColor, width: 1),
            right: BorderSide(color: Colors.transparent),
            top: BorderSide(color: Colors.transparent),
          ),
        ),
        lineBarsData: [
          LineChartBarData(
            isCurved: true,
            color: HYAppTheme.norTextColors,
            barWidth: 2,
            isStrokeCapRound: true,
            dotData: FlDotData(show: false),
            belowBarData: BarAreaData(show: false),
            spots: _opusCountRange.isEmpty ? [] : getFlSpotList(),
          )
        ],
        lineTouchData: LineTouchData(
          handleBuiltInTouches: true,
          touchTooltipData: LineTouchTooltipData(
            tooltipBgColor: HYAppTheme.norGrayColor,
          ),
        ),
        gridData: FlGridData(show: true),
        titlesData: FlTitlesData(
          bottomTitles: AxisTitles(
            sideTitles: SideTitles(
              showTitles: true,
              reservedSize: 40,
              interval: 1,
              getTitlesWidget: (value, meta) {
                const style = TextStyle(
                  color: HYAppTheme.norGrayColor,
                  fontSize: HYAppTheme.xSmallFontSize,
                );

                Widget text;
                if (_opusCountRange.isEmpty || value.toInt() % 5 != 0) {
                  text = Container();
                } else {
                  String dateString = _opusCountRange[value.toInt()]
                      .date
                      .toString()
                      .substring(5, 10);
                  text = Text(
                    dateString,
                    style: style,
                  );
                }
                return SideTitleWidget(
                  child: text,
                  axisSide: meta.axisSide,
                  space: 10,
                );
              },
            ),
          ),
          rightTitles: AxisTitles(
            sideTitles: SideTitles(showTitles: false),
          ),
          topTitles: AxisTitles(
            sideTitles: SideTitles(showTitles: false),
          ),
          leftTitles: AxisTitles(
            sideTitles: SideTitles(
              getTitlesWidget: (double value, TitleMeta meta) {
                const style = TextStyle(
                  color: HYAppTheme.norGrayColor,
                  fontSize: HYAppTheme.xSmallFontSize,
                );
                String text;
                switch (value.toInt()) {
                  case 2:
                    text = '2%';
                    break;
                  case 4:
                    text = '4%';
                    break;
                  case 6:
                    text = '6%';
                    break;
                  case 8:
                    text = '8%';
                    break;
                  default:
                    return Container();
                }

                return Text(text, style: style, textAlign: TextAlign.center);
              },
              showTitles: true,
              interval: 1,
              reservedSize: 30,
            ),
          ),
        ),
      ),
      swapAnimationDuration: Duration(milliseconds: 1000),
    );
  }

  Widget buildLineChartSample02() {
    return AspectRatio(
      aspectRatio: 1.23,
      child: Container(
        decoration: const BoxDecoration(
          borderRadius: BorderRadius.all(Radius.circular(10)),
          gradient: LinearGradient(
            colors: [
              Color(0x77ef96c5),
              Color(0x77ccfbff),
            ],
            begin: Alignment.bottomCenter,
            end: Alignment.topCenter,
          ),
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            SizedBox(
              height: 37.px,
            ),
            Text(
              '近30日投稿UP主趋势',
              style: TextStyle(
                color: HYAppTheme.norTextColors,
                fontSize: 16.px,
              ),
              textAlign: TextAlign.center,
            ),
            SizedBox(
              height: 4.px,
            ),
            Text(
              '趋势图 (2)',
              style: TextStyle(
                color: Colors.black,
                fontSize: HYAppTheme.smallFontSize,
                fontWeight: FontWeight.bold,
                letterSpacing: 2,
              ),
              textAlign: TextAlign.center,
            ),
            SizedBox(
              height: 37.px,
            ),
            Expanded(
              child: Padding(
                padding: EdgeInsets.only(right: 16.px, left: 6.px),
                child: buildLineChart02(),
              ),
            ),
            SizedBox(
              height: 10.px,
            ),
          ],
        ),
      ),
    );
  }

  Widget buildLineChart02() {
    return LineChart(
      LineChartData(
        minX: 0,
        maxX: _opusCountRange.length.toDouble(),
        maxY: 10,
        minY: 0,
        borderData: FlBorderData(
          show: true,
          border: const Border(
            bottom: BorderSide(color: HYAppTheme.norGrayColor, width: 1),
            left: BorderSide(color: HYAppTheme.norGrayColor, width: 1),
            right: BorderSide(color: Colors.transparent),
            top: BorderSide(color: Colors.transparent),
          ),
        ),
        lineBarsData: [
          LineChartBarData(
            dotData: FlDotData(
              show: false,
            ),
            belowBarData: BarAreaData(
              show: true,
              gradient: LinearGradient(
                colors: [
                  const Color(0xff23b6e6),
                  const Color(0xff02d39a),
                ].map((color) => color.withOpacity(0.3)).toList(),
                begin: Alignment.centerLeft,
                end: Alignment.centerRight,
              ),
            ),
            isCurved: true,
            color: HYAppTheme.norTextColors,
            barWidth: 2,
            isStrokeCapRound: true,
            spots: _opusCountRange.isEmpty ? [] : getFlSpotList(),
          )
        ],
        lineTouchData: LineTouchData(
          handleBuiltInTouches: true,
          touchTooltipData: LineTouchTooltipData(
            tooltipBgColor: HYAppTheme.norGrayColor,
          ),
        ),
        gridData: FlGridData(
          ///添加分割线
          horizontalInterval: 1,
          verticalInterval: 1,
          getDrawingHorizontalLine: (value) {
            return FlLine(
              color: const Color(0xff37434d),
              strokeWidth: 1,
            );
          },
          // getDrawingVerticalLine: (value) {
          //   return FlLine(
          //     color: const Color(0xff37434d),
          //     strokeWidth: 1,
          //   );
          // },
          show: true,
        ),
        titlesData: FlTitlesData(
          bottomTitles: AxisTitles(
            sideTitles: SideTitles(
              showTitles: true,
              reservedSize: 40,
              interval: 1,
              getTitlesWidget: (value, meta) {
                const style = TextStyle(
                  color: HYAppTheme.norGrayColor,
                  fontSize: HYAppTheme.xSmallFontSize,
                );

                Widget text;
                if (_opusCountRange.isEmpty || value.toInt() % 5 != 0) {
                  text = Container();
                } else {
                  String dateString = _opusCountRange[value.toInt()]
                      .date
                      .toString()
                      .substring(5, 10);
                  text = Text(
                    dateString,
                    style: style,
                  );
                }
                return SideTitleWidget(
                  child: text,
                  axisSide: meta.axisSide,
                  space: 10,
                );
              },
            ),
          ),
          rightTitles: AxisTitles(
            sideTitles: SideTitles(showTitles: false),
          ),
          topTitles: AxisTitles(
            sideTitles: SideTitles(showTitles: false),
          ),
          leftTitles: AxisTitles(
            sideTitles: SideTitles(
              getTitlesWidget: (double value, TitleMeta meta) {
                const style = TextStyle(
                  color: HYAppTheme.norGrayColor,
                  fontSize: HYAppTheme.xSmallFontSize,
                );
                String text;
                switch (value.toInt()) {
                  case 2:
                    text = '2%';
                    break;
                  case 4:
                    text = '4%';
                    break;
                  case 6:
                    text = '6%';
                    break;
                  case 8:
                    text = '8%';
                    break;
                  default:
                    return Container();
                }

                return Text(text, style: style, textAlign: TextAlign.center);
              },
              showTitles: true,
              interval: 1,
              reservedSize: 30,
            ),
          ),
        ),
      ),
      swapAnimationDuration: Duration(milliseconds: 1000),
    );
  }

  Widget buildLineChartSample03() {
    return AspectRatio(
      aspectRatio: 1.23,
      child: Container(
        decoration: const BoxDecoration(
          borderRadius: BorderRadius.all(Radius.circular(10)),
          gradient: LinearGradient(
            colors: [
              Color(0x77ef96c5),
              Color(0x77ccfbff),
            ],
            begin: Alignment.bottomCenter,
            end: Alignment.topCenter,
          ),
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            SizedBox(
              height: 37.px,
            ),
            Text(
              '近30日投稿UP主趋势',
              style: TextStyle(
                color: HYAppTheme.norTextColors,
                fontSize: 16.px,
              ),
              textAlign: TextAlign.center,
            ),
            SizedBox(
              height: 4.px,
            ),
            const Text(
              '趋势图 (3)',
              style: TextStyle(
                color: Colors.black,
                fontSize: HYAppTheme.smallFontSize,
                fontWeight: FontWeight.bold,
                letterSpacing: 2,
              ),
              textAlign: TextAlign.center,
            ),
            SizedBox(
              height: 37.px,
            ),
            Expanded(
              child: Padding(
                padding: EdgeInsets.only(right: 16.px, left: 6.px),
                child: buildLineChart03(),
              ),
            ),
            SizedBox(
              height: 10.px,
            ),
          ],
        ),
      ),
    );
  }

  Widget buildLineChart03() {
    return LineChart(
      LineChartData(
        minX: 0,
        maxX: _opusCountRange.length.toDouble(),
        maxY: 10,
        minY: 0,
        borderData: FlBorderData(
          show: true,
          border: const Border(
            bottom: BorderSide(color: HYAppTheme.norGrayColor, width: 1),
            left: BorderSide(color: HYAppTheme.norGrayColor, width: 1),
            right: BorderSide(color: Colors.transparent),
            top: BorderSide(color: Colors.transparent),
          ),
        ),
        lineBarsData: [
          LineChartBarData(
            isStepLineChart: true,
            isCurved: false,
            color: HYAppTheme.norTextColors,
            barWidth: 2,
            isStrokeCapRound: true,
            spots: _opusCountRange.isEmpty ? [] : getFlSpotList(),
            belowBarData: BarAreaData(
              show: true,
              gradient: LinearGradient(
                colors: [
                  Colors.orange.withOpacity(0.5),
                  Colors.orange.withOpacity(0.0),
                ],
                stops: const [0.5, 1.0],
                begin: Alignment.topCenter,
                end: Alignment.bottomCenter,
              ),
              spotsLine: BarAreaSpotsLine(
                show: true,
                flLineStyle: FlLine(
                  color: Colors.blue,
                  strokeWidth: 1,
                ),
                checkToShowSpotLine: (spot) {
                  if (spot.x == 0 || spot.x == _opusCountRange.length - 1) {
                    return false;
                  }
                  return true;
                },
              ),
            ),
            dotData: FlDotData(
                show: true,
                getDotPainter: (spot, percent, barData, index) {
                  if (index % 2 == 0) {
                    return FlDotCirclePainter(
                        radius: 2,
                        color: Colors.white,
                        strokeWidth: 1,
                        strokeColor: Colors.deepOrange);
                  } else {
                    return FlDotSquarePainter(
                      size: 2,
                      color: Colors.white,
                      strokeWidth: 1,
                      strokeColor: Colors.deepOrange,
                    );
                  }
                },
                checkToShowDot: (spot, barData) {
                  return spot.x != 0 && spot.x != 6;
                }),
          )
        ],
        lineTouchData: LineTouchData(
          getTouchedSpotIndicator:
              (LineChartBarData barData, List<int> spotIndexes) {
            return spotIndexes.map((spotIndex) {
              final spot = barData.spots[spotIndex];
              if (spot.x == 0 || spot.x == _opusCountRange.length - 1) {
                return null;
              }
              return TouchedSpotIndicatorData(
                FlLine(color: Colors.blue, strokeWidth: 4),
                FlDotData(
                  getDotPainter: (spot, percent, barData, index) {
                    if (index % 2 == 0) {
                      return FlDotCirclePainter(
                          radius: 4,
                          color: Colors.white,
                          strokeWidth: 2,
                          strokeColor: Colors.deepOrange);
                    } else {
                      return FlDotSquarePainter(
                        size: 4,
                        color: Colors.white,
                        strokeWidth: 2,
                        strokeColor: Colors.deepOrange,
                      );
                    }
                  },
                ),
              );
            }).toList();
          },
          touchTooltipData: LineTouchTooltipData(
            tooltipBgColor: Colors.blueAccent,
            getTooltipItems: (List<LineBarSpot> touchedBarSpots) {
              return touchedBarSpots.map(
                (barSpot) {
                  final flSpot = barSpot;
                  if (flSpot.x == 0 || flSpot.x == _opusCountRange.length - 1) {
                    return null;
                  }

                  TextAlign textAlign;
                  switch (flSpot.x.toInt()) {
                    case 1:
                      textAlign = TextAlign.left;
                      break;
                    // case 5:
                    //   textAlign = TextAlign.right;
                    //   break;
                    default:
                      textAlign = TextAlign.center;
                  }
                  DateTime? dateTime = _opusCountRange[flSpot.x.toInt()].date;
                  return LineTooltipItem(
                    '日期：${dateTime?.month}月${dateTime?.day}日\n',
                    const TextStyle(
                      color: Colors.white,
                      fontWeight: FontWeight.bold,
                    ),
                    children: [
                      TextSpan(
                        text: flSpot.y.toString(),
                        style: TextStyle(
                          color: Colors.grey[100],
                          fontWeight: FontWeight.normal,
                        ),
                      ),
                      const TextSpan(
                        text: ' % ',
                        style: TextStyle(
                          fontStyle: FontStyle.italic,
                          fontWeight: FontWeight.normal,
                        ),
                      ),
                      const TextSpan(
                        text: '投稿比率',
                        style: TextStyle(
                          fontWeight: FontWeight.normal,
                        ),
                      ),
                    ],
                    textAlign: textAlign,
                  );
                },
              ).toList();
            },
          ),
        ),
        extraLinesData: ExtraLinesData(horizontalLines: [
          HorizontalLine(
            y: 6,
            color: Colors.green.withOpacity(0.8),
            strokeWidth: 1,
            dashArray: [10, 2],
          ),
        ]),
        gridData: FlGridData(show: true),
        titlesData: FlTitlesData(
          bottomTitles: AxisTitles(
            sideTitles: SideTitles(
              showTitles: true,
              reservedSize: 40,
              interval: 1,
              getTitlesWidget: (value, meta) {
                const style = TextStyle(
                  color: HYAppTheme.norGrayColor,
                  fontSize: HYAppTheme.xSmallFontSize,
                );

                Widget text;
                if (_opusCountRange.isEmpty || value.toInt() % 5 != 0) {
                  text = Container();
                } else {
                  String dateString = _opusCountRange[value.toInt()]
                      .date
                      .toString()
                      .substring(5, 10);
                  text = Text(
                    dateString,
                    style: style,
                  );
                }
                return SideTitleWidget(
                  child: text,
                  axisSide: meta.axisSide,
                  space: 10,
                );
              },
            ),
          ),
          rightTitles: AxisTitles(
            sideTitles: SideTitles(showTitles: false),
          ),
          topTitles: AxisTitles(
            sideTitles: SideTitles(showTitles: false),
          ),
          leftTitles: AxisTitles(
            sideTitles: SideTitles(
              getTitlesWidget: (double value, TitleMeta meta) {
                const style = TextStyle(
                  color: HYAppTheme.norGrayColor,
                  fontSize: HYAppTheme.xSmallFontSize,
                );
                String text;
                switch (value.toInt()) {
                  case 2:
                    text = '2%';
                    break;
                  case 4:
                    text = '4%';
                    break;
                  case 6:
                    text = '6%';
                    break;
                  case 8:
                    text = '8%';
                    break;
                  default:
                    return Container();
                }

                return Text(text, style: style, textAlign: TextAlign.center);
              },
              showTitles: true,
              interval: 1,
              reservedSize: 30,
            ),
          ),
        ),
      ),
      swapAnimationDuration: const Duration(milliseconds: 1000),
    );
  }

  Widget buildLineChartSample04() {
    return AspectRatio(
      aspectRatio: 1.23,
      child: Container(
        decoration: const BoxDecoration(
          borderRadius: BorderRadius.all(Radius.circular(10)),
          gradient: LinearGradient(
            colors: [
              Color(0x77ef96c5),
              Color(0x77ccfbff),
            ],
            begin: Alignment.bottomCenter,
            end: Alignment.topCenter,
          ),
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            SizedBox(
              height: 37.px,
            ),
            Text(
              '近30日投稿UP主趋势',
              style: TextStyle(
                color: HYAppTheme.norTextColors,
                fontSize: 16.px,
              ),
              textAlign: TextAlign.center,
            ),
            SizedBox(
              height: 4.px,
            ),
            Text(
              '趋势图 (4)',
              style: TextStyle(
                color: Colors.black,
                fontSize: HYAppTheme.smallFontSize,
                fontWeight: FontWeight.bold,
                letterSpacing: 2,
              ),
              textAlign: TextAlign.center,
            ),
            SizedBox(
              height: 37.px,
            ),
            Expanded(
              child: Padding(
                padding: EdgeInsets.only(right: 16.px, left: 6.px),
                child: buildLineChart04(),
              ),
            ),
            SizedBox(
              height: 10.px,
            ),
          ],
        ),
      ),
    );
  }

  Widget buildLineChart04() {
    const cutOffYValue = 6.0;
    return LineChart(
      LineChartData(
        minX: 0,
        maxX: _opusCountRange.length.toDouble(),
        maxY: 8,
        minY: 5,
        borderData: FlBorderData(
          show: true,
          border: const Border(
            bottom: BorderSide(color: HYAppTheme.norGrayColor, width: 1),
            left: BorderSide(color: HYAppTheme.norGrayColor, width: 1),
            right: BorderSide(color: Colors.transparent),
            top: BorderSide(color: Colors.transparent),
          ),
        ),
        lineBarsData: [
          LineChartBarData(
            isCurved: true,
            color: HYAppTheme.norTextColors,
            barWidth: 2,
            isStrokeCapRound: true,
            dotData: FlDotData(show: false),
            belowBarData: BarAreaData(
              show: true,
              color: Colors.deepPurple.withOpacity(0.4),
              cutOffY: cutOffYValue,
              applyCutOffY: true,
            ),
            aboveBarData: BarAreaData(
              show: true,
              color: Colors.orange.withOpacity(0.6),
              cutOffY: cutOffYValue,
              applyCutOffY: true,
            ),
            spots: _opusCountRange.isEmpty ? [] : getFlSpotList(),
          )
        ],
        lineTouchData: LineTouchData(
          handleBuiltInTouches: true,
          touchTooltipData: LineTouchTooltipData(
            tooltipBgColor: HYAppTheme.norGrayColor,
          ),
        ),
        gridData: FlGridData(show: true),
        titlesData: FlTitlesData(
          bottomTitles: AxisTitles(
            sideTitles: SideTitles(
              showTitles: true,
              reservedSize: 40,
              interval: 1,
              getTitlesWidget: (value, meta) {
                const style = TextStyle(
                  color: HYAppTheme.norGrayColor,
                  fontSize: HYAppTheme.xSmallFontSize,
                );

                Widget text;
                if (_opusCountRange.isEmpty || value.toInt() % 5 != 0) {
                  text = Container();
                } else {
                  String dateString = _opusCountRange[value.toInt()]
                      .date
                      .toString()
                      .substring(5, 10);
                  text = Text(
                    dateString,
                    style: style,
                  );
                }
                return SideTitleWidget(
                  child: text,
                  axisSide: meta.axisSide,
                  space: 10,
                );
              },
            ),
          ),
          rightTitles: AxisTitles(
            sideTitles: SideTitles(showTitles: false),
          ),
          topTitles: AxisTitles(
            sideTitles: SideTitles(showTitles: false),
          ),
          leftTitles: AxisTitles(
            sideTitles: SideTitles(
              getTitlesWidget: (double value, TitleMeta meta) {
                const style = TextStyle(
                  color: HYAppTheme.norGrayColor,
                  fontSize: HYAppTheme.xSmallFontSize,
                );
                String text;
                switch (value.toInt()) {
                  case 5:
                    text = '5%';
                    break;
                  case 6:
                    text = '6%';
                    break;
                  case 8:
                    text = '8%';
                    break;
                  default:
                    return Container();
                }
                return Text(text, style: style, textAlign: TextAlign.center);
              },
              showTitles: true,
              interval: 1,
              reservedSize: 30,
            ),
          ),
        ),
      ),
      swapAnimationDuration: Duration(milliseconds: 1000),
    );
  }

  Widget buildLineChartSample05() {
    return AspectRatio(
      aspectRatio: 1.23,
      child: Container(
        decoration: const BoxDecoration(
          borderRadius: BorderRadius.all(Radius.circular(10)),
          gradient: LinearGradient(
            colors: [
              Color(0x77ef96c5),
              Color(0x77ccfbff),
            ],
            begin: Alignment.bottomCenter,
            end: Alignment.topCenter,
          ),
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            SizedBox(
              height: 37.px,
            ),
            Text(
              '近30日投稿UP主趋势',
              style: TextStyle(
                color: HYAppTheme.norTextColors,
                fontSize: 16.px,
              ),
              textAlign: TextAlign.center,
            ),
            SizedBox(
              height: 4.px,
            ),
            Text(
              '趋势图 (5)',
              style: TextStyle(
                color: Colors.black,
                fontSize: HYAppTheme.smallFontSize,
                fontWeight: FontWeight.bold,
                letterSpacing: 2,
              ),
              textAlign: TextAlign.center,
            ),
            SizedBox(
              height: 37.px,
            ),
            Expanded(
              child: Padding(
                padding: EdgeInsets.only(right: 16.px, left: 6.px),
                child: buildLineChart05(),
              ),
            ),
            SizedBox(
              height: 10.px,
            ),
          ],
        ),
      ),
    );
  }

  Widget buildLineChart05() {
    final List<int> showIndexes = const [1, 12, 23];
    final lineBarsData = [
      LineChartBarData(
        showingIndicators: showIndexes,
        spots: _opusCountRange.isEmpty ? [] : getFlSpotList(),
        isCurved: true,
        barWidth: 4,
        shadow: const Shadow(
          blurRadius: 8,
          color: Colors.black,
        ),
        belowBarData: BarAreaData(
          show: true,
          gradient: LinearGradient(
            colors: [
              const Color(0xff12c2e9).withOpacity(0.4),
              const Color(0xffc471ed).withOpacity(0.4),
              const Color(0xfff64f59).withOpacity(0.4),
            ],
            begin: Alignment.centerLeft,
            end: Alignment.centerRight,
          ),
        ),
        dotData: FlDotData(show: false),
        gradient: const LinearGradient(
          colors: [
            Color(0xff12c2e9),
            Color(0xffc471ed),
            Color(0xfff64f59),
          ],
          stops: [0.1, 0.4, 0.9],
          begin: Alignment.centerLeft,
          end: Alignment.centerRight,
        ),
      ),
    ];
    final tooltipsOnBar = lineBarsData[0];
    return LineChart(
      LineChartData(
        showingTooltipIndicators: showIndexes.map((index) {
          return ShowingTooltipIndicators([
            LineBarSpot(
                tooltipsOnBar,
                lineBarsData.indexOf(tooltipsOnBar),
                tooltipsOnBar.spots.isNotEmpty
                    ? tooltipsOnBar.spots[index]
                    : FlSpot(0, 0)),
          ]);
        }).toList(),
        lineTouchData: LineTouchData(
          enabled: false,
          getTouchedSpotIndicator:
              (LineChartBarData barData, List<int> spotIndexes) {
            return spotIndexes.map((index) {
              return TouchedSpotIndicatorData(
                FlLine(
                  color: Colors.pink,
                ),
                FlDotData(
                  show: true,
                  getDotPainter: (spot, percent, barData, index) =>
                      FlDotCirclePainter(
                    radius: 8,
                    color: lerpGradient(
                      barData.gradient!.colors,
                      barData.gradient!.stops!,
                      percent / 100,
                    ),
                    strokeWidth: 2,
                    strokeColor: Colors.black,
                  ),
                ),
              );
            }).toList();
          },
          touchTooltipData: LineTouchTooltipData(
            tooltipBgColor: Colors.pink,
            tooltipRoundedRadius: 8,
            getTooltipItems: (List<LineBarSpot> lineBarsSpot) {
              return lineBarsSpot.map((lineBarSpot) {
                return LineTooltipItem(
                  lineBarSpot.y.toString(),
                  const TextStyle(
                      color: Colors.white, fontWeight: FontWeight.bold),
                );
              }).toList();
            },
          ),
        ),
        lineBarsData: lineBarsData,
        minX: 0,
        maxX: _opusCountRange.length.toDouble(),
        maxY: 10,
        minY: 0,
        borderData: FlBorderData(
          show: true,
          border: const Border(
            bottom: BorderSide(color: HYAppTheme.norGrayColor, width: 1),
            left: BorderSide(color: HYAppTheme.norGrayColor, width: 1),
            right: BorderSide(color: Colors.transparent),
            top: BorderSide(color: Colors.transparent),
          ),
        ),
        gridData: FlGridData(show: true),
        titlesData: FlTitlesData(
          bottomTitles: AxisTitles(
            sideTitles: SideTitles(
              showTitles: true,
              reservedSize: 40,
              interval: 1,
              getTitlesWidget: (value, meta) {
                const style = TextStyle(
                  fontFamily: 'Digital',
                  color: HYAppTheme.norGrayColor,
                  fontSize: HYAppTheme.xSmallFontSize,
                );

                Widget text;
                if (_opusCountRange.isEmpty || value.toInt() % 5 != 0) {
                  text = Container();
                } else {
                  String dateString = _opusCountRange[value.toInt()]
                      .date
                      .toString()
                      .substring(5, 10);
                  text = Text(
                    dateString,
                    style: style,
                  );
                }
                return SideTitleWidget(
                  child: text,
                  axisSide: meta.axisSide,
                  space: 10,
                );
              },
            ),
          ),
          rightTitles: AxisTitles(
            axisNameWidget: Text(
              '投稿率',
              style: TextStyle(fontSize: 10),
            ),
            sideTitles: SideTitles(
              showTitles: false,
              reservedSize: 0,
            ),
          ),
          topTitles: AxisTitles(
            sideTitles: SideTitles(showTitles: false),
          ),
          leftTitles: AxisTitles(
            sideTitles: SideTitles(
              getTitlesWidget: (double value, TitleMeta meta) {
                const style = TextStyle(
                  color: HYAppTheme.norGrayColor,
                  fontSize: HYAppTheme.xSmallFontSize,
                );
                String text;
                switch (value.toInt()) {
                  case 2:
                    text = '2%';
                    break;
                  case 4:
                    text = '4%';
                    break;
                  case 6:
                    text = '6%';
                    break;
                  case 8:
                    text = '8%';
                    break;
                  default:
                    return Container();
                }

                return Text(text, style: style, textAlign: TextAlign.center);
              },
              showTitles: true,
              interval: 1,
              reservedSize: 30,
            ),
          ),
        ),
      ),
      swapAnimationDuration: Duration(milliseconds: 1000),
    );
  }

  Widget buildLineChartSample06() {
    return AspectRatio(
      aspectRatio: 1.23,
      child: Container(
        decoration: const BoxDecoration(
          borderRadius: BorderRadius.all(Radius.circular(10)),
          gradient: LinearGradient(
            colors: [
              Color(0x77ef96c5),
              Color(0x77ccfbff),
            ],
            begin: Alignment.bottomCenter,
            end: Alignment.topCenter,
          ),
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            SizedBox(
              height: 37.px,
            ),
            Text(
              '近30日投稿UP主趋势',
              style: TextStyle(
                color: HYAppTheme.norTextColors,
                fontSize: 16.px,
              ),
              textAlign: TextAlign.center,
            ),
            SizedBox(
              height: 4.px,
            ),
            Text(
              '趋势图 (6)',
              style: TextStyle(
                color: Colors.black,
                fontSize: HYAppTheme.smallFontSize,
                fontWeight: FontWeight.bold,
                letterSpacing: 2,
              ),
              textAlign: TextAlign.center,
            ),
            SizedBox(
              height: 37.px,
            ),
            Expanded(
              child: Padding(
                padding: EdgeInsets.only(right: 16.px, left: 6.px),
                child: buildLineChart06(),
              ),
            ),
            SizedBox(
              height: 10.px,
            ),
          ],
        ),
      ),
    );
  }

  Widget buildLineChart06() {
    return LineChart(
      LineChartData(
        minX: 0,
        maxX: _opusCountRange.length.toDouble(),
        maxY: 10,
        minY: 0,
        borderData: FlBorderData(
          show: true,
          border: const Border(
            bottom: BorderSide(color: HYAppTheme.norGrayColor, width: 1),
            left: BorderSide(color: HYAppTheme.norGrayColor, width: 1),
            right: BorderSide(color: Colors.transparent),
            top: BorderSide(color: Colors.transparent),
          ),
        ),
        lineBarsData: [
          LineChartBarData(
            isCurved: true,
            color: HYAppTheme.norTextColors,
            barWidth: 2,
            isStrokeCapRound: true,
            dotData: FlDotData(show: false),
            belowBarData: BarAreaData(show: false),
            spots: _opusCountRange.isEmpty ? [] : getFlSpotList(),
          ),
          LineChartBarData(
            isCurved: true,
            color: HYAppTheme.norTextColors,
            barWidth: 2,
            isStrokeCapRound: true,
            dotData: FlDotData(show: false),
            belowBarData: BarAreaData(show: false),
            spots: _opusCountRange02.isEmpty ? [] : getFlSpotList02(),
          ),
        ],
        betweenBarsData: [
          BetweenBarsData(
            fromIndex: 0,
            toIndex: 1,
            color: Colors.red.withOpacity(0.3),
          )
        ],
        lineTouchData: LineTouchData(
          handleBuiltInTouches: true,
          touchTooltipData: LineTouchTooltipData(
            tooltipBgColor: HYAppTheme.norGrayColor,
          ),
        ),
        gridData: FlGridData(
          show: true,
          drawVerticalLine: false,
          horizontalInterval: 1,
          checkToShowHorizontalLine: (double value) {
            return value == 1 || value == 6 || value == 5;
          },
        ),
        titlesData: FlTitlesData(
          bottomTitles: AxisTitles(
            sideTitles: SideTitles(
              showTitles: true,
              reservedSize: 40,
              interval: 1,
              getTitlesWidget: (value, meta) {
                const style = TextStyle(
                  color: HYAppTheme.norGrayColor,
                  fontSize: HYAppTheme.xSmallFontSize,
                );

                Widget text;
                if (_opusCountRange.isEmpty || value.toInt() % 5 != 0) {
                  text = Container();
                } else {
                  String dateString = _opusCountRange[value.toInt()]
                      .date
                      .toString()
                      .substring(5, 10);
                  text = Text(
                    dateString,
                    style: style,
                  );
                }
                return SideTitleWidget(
                  child: text,
                  axisSide: meta.axisSide,
                  space: 10,
                );
              },
            ),
          ),
          rightTitles: AxisTitles(
            sideTitles: SideTitles(showTitles: false),
          ),
          topTitles: AxisTitles(
            sideTitles: SideTitles(showTitles: false),
          ),
          leftTitles: AxisTitles(
            sideTitles: SideTitles(
              getTitlesWidget: (double value, TitleMeta meta) {
                const style = TextStyle(
                  color: HYAppTheme.norGrayColor,
                  fontSize: HYAppTheme.xSmallFontSize,
                );
                String text;
                switch (value.toInt()) {
                  case 2:
                    text = '2%';
                    break;
                  case 4:
                    text = '4%';
                    break;
                  case 6:
                    text = '6%';
                    break;
                  case 8:
                    text = '8%';
                    break;
                  default:
                    return Container();
                }
                return Text(text, style: style, textAlign: TextAlign.center);
              },
              showTitles: true,
              interval: 1,
              reservedSize: 30,
            ),
          ),
        ),
      ),
      swapAnimationDuration: Duration(milliseconds: 1000),
    );
  }

  Widget buildLineChartSample07() {
    return AspectRatio(
      aspectRatio: 1.23,
      child: Container(
        decoration: const BoxDecoration(
          borderRadius: BorderRadius.all(Radius.circular(10)),
          gradient: LinearGradient(
            colors: [
              Color(0x77ef96c5),
              Color(0x77ccfbff),
            ],
            begin: Alignment.bottomCenter,
            end: Alignment.topCenter,
          ),
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            SizedBox(
              height: 37.px,
            ),
            Text(
              '近30日投稿UP主趋势',
              style: TextStyle(
                color: HYAppTheme.norTextColors,
                fontSize: 16.px,
              ),
              textAlign: TextAlign.center,
            ),
            SizedBox(
              height: 4.px,
            ),
            Text(
              '趋势图 (7)',
              style: TextStyle(
                color: Colors.black,
                fontSize: HYAppTheme.smallFontSize,
                fontWeight: FontWeight.bold,
                letterSpacing: 2,
              ),
              textAlign: TextAlign.center,
            ),
            SizedBox(
              height: 37.px,
            ),
            Expanded(
              child: Padding(
                padding: EdgeInsets.only(right: 16.px, left: 6.px),
                child: buildLineChart07(),
              ),
            ),
            SizedBox(
              height: 10.px,
            ),
          ],
        ),
      ),
    );
  }

  Widget buildLineChart07() {
    return LineChart(
      LineChartData(
        minX: 0,
        maxX: _opusCountRange.length.toDouble(),
        maxY: 10,
        minY: 0,
        borderData: FlBorderData(
          show: true,
          border: const Border(
            bottom: BorderSide(color: HYAppTheme.norGrayColor, width: 1),
            left: BorderSide(color: HYAppTheme.norGrayColor, width: 1),
            right: BorderSide(color: Colors.transparent),
            top: BorderSide(color: Colors.transparent),
          ),
        ),
        lineBarsData: [
          LineChartBarData(
            isCurved: true,
            color: HYAppTheme.norTextColors,
            barWidth: 2,
            isStrokeCapRound: true,
            dotData: FlDotData(show: false),
            belowBarData: BarAreaData(show: false),
            spots: _opusCountRange.isEmpty ? [] : getFlSpotList(),
          )
        ],
        lineTouchData: LineTouchData(
          handleBuiltInTouches: true,
          touchTooltipData: LineTouchTooltipData(
            tooltipBgColor: HYAppTheme.norGrayColor,
          ),
        ),
        gridData: FlGridData(show: true),
        titlesData: FlTitlesData(
          bottomTitles: AxisTitles(
            sideTitles: SideTitles(
              showTitles: true,
              reservedSize: 40,
              interval: 1,
              getTitlesWidget: (value, meta) {
                const style = TextStyle(
                  color: HYAppTheme.norGrayColor,
                  fontSize: HYAppTheme.xSmallFontSize,
                );

                Widget text;
                if (_opusCountRange.isEmpty || value.toInt() % 5 != 0) {
                  text = Container();
                } else {
                  String dateString = _opusCountRange[value.toInt()]
                      .date
                      .toString()
                      .substring(5, 10);
                  text = Text(
                    dateString,
                    style: style,
                  );
                }
                return SideTitleWidget(
                  child: text,
                  axisSide: meta.axisSide,
                  space: 10,
                );
              },
            ),
          ),
          rightTitles: AxisTitles(
            sideTitles: SideTitles(showTitles: false),
          ),
          topTitles: AxisTitles(
            sideTitles: SideTitles(showTitles: false),
          ),
          leftTitles: AxisTitles(
            sideTitles: SideTitles(
              getTitlesWidget: (double value, TitleMeta meta) {
                const style = TextStyle(
                  color: HYAppTheme.norGrayColor,
                  fontSize: HYAppTheme.xSmallFontSize,
                );
                String text;
                switch (value.toInt()) {
                  case 2:
                    text = '2%';
                    break;
                  case 4:
                    text = '4%';
                    break;
                  case 6:
                    text = '6%';
                    break;
                  case 8:
                    text = '8%';
                    break;
                  default:
                    return Container();
                }

                return Text(text, style: style, textAlign: TextAlign.center);
              },
              showTitles: true,
              interval: 1,
              reservedSize: 30,
            ),
          ),
        ),
      ),
      swapAnimationDuration: Duration(milliseconds: 1000),
    );
  }
}

class BuildLineChartSample08 extends StatefulWidget {
  const BuildLineChartSample08({Key? key}) : super(key: key);

  @override
  State<BuildLineChartSample08> createState() => _BuildLineChartSample08State();
}

class _BuildLineChartSample08State extends State<BuildLineChartSample08> {
  List<Range> _opusCountRange = [];

  List<Color> gradientColors = const [
    Color(0xffEEF3FE),
    Color(0xffEEF3FE),
  ];

  Future<ui.Image> loadImage(String asset) async {
    final data = await rootBundle.load(asset);
    final codec = await ui.instantiateImageCodec(data.buffer.asUint8List());
    final fi = await codec.getNextFrame();
    return fi.image;
  }

  Future<SizedPicture> loadSvg() async {
    const rawSvg =
        '<svg height="14" width="14" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd" transform="translate(-.000014)"><circle cx="7" cy="7" fill="#495DFF" r="7"/><path d="m7 10.9999976c1.6562389 0 2.99998569-1.34374678 2.99998569-2.99999283s-1.34374679-4.99998808-2.99998569-4.99998808c-1.6562532 0-3 3.34374203-3 4.99998808s1.3437468 2.99999283 3 2.99999283z" fill="#fff" fill-rule="nonzero"/></g></svg>';

    final svgRoot = await svg.fromSvgString(rawSvg, rawSvg);

    final picture = svgRoot.toPicture();
    final sizedPicture = SizedPicture(picture, 14, 14);
    return sizedPicture;
  }

  @override
  void initState() {
    HYJsonParse.getBigData().then((value) {
      setState(() {
        _opusCountRange = value.lastMonthOpus.opusCountRange;
      });
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<SizedPicture>(
        future: loadSvg(),
        builder: (BuildContext context, imageSnapshot) {
          if (imageSnapshot.connectionState == ConnectionState.done) {
            return Stack(
              children: <Widget>[
                AspectRatio(
                  aspectRatio: 1.37,
                  child: Container(
                    decoration: const BoxDecoration(
                      borderRadius: BorderRadius.all(Radius.circular(10)),
                      gradient: LinearGradient(
                        colors: [
                          Color(0x77ef96c5),
                          Color(0x77ccfbff),
                        ],
                        begin: Alignment.bottomCenter,
                        end: Alignment.topCenter,
                      ),
                    ),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.stretch,
                      children: [
                        SizedBox(
                          height: 37.px,
                        ),
                        Text(
                          '近30日投稿UP主趋势',
                          style: TextStyle(
                            color: HYAppTheme.norTextColors,
                            fontSize: 16.px,
                          ),
                          textAlign: TextAlign.center,
                        ),
                        SizedBox(
                          height: 4.px,
                        ),
                        Text(
                          '趋势图 (8)',
                          style: TextStyle(
                            color: Colors.black,
                            fontSize: HYAppTheme.smallFontSize,
                            fontWeight: FontWeight.bold,
                            letterSpacing: 2,
                          ),
                          textAlign: TextAlign.center,
                        ),
                        SizedBox(
                          height: 30.px,
                        ),
                        Expanded(
                          child: Padding(
                            padding: EdgeInsets.only(right: 16.px, left: 6.px),
                            child: buildLineChart08(imageSnapshot.data!),
                          ),
                        ),
                        SizedBox(
                          height: 10.px,
                        ),
                      ],
                    ),
                  ),
                ),
              ],
            );
          } else {
            return const CircularProgressIndicator();
          }
        });
  }

  Widget buildLineChart08(SizedPicture sizedPicture) {
    return LineChart(
      LineChartData(
        rangeAnnotations: RangeAnnotations(
          verticalRangeAnnotations: [
            VerticalRangeAnnotation(
              x1: 2,
              x2: 5,
              color: const Color(0xffD5DAE5),
            ),
            VerticalRangeAnnotation(
              x1: 8,
              x2: 9,
              color: const Color(0xffD5DAE5),
            ),
          ],
          horizontalRangeAnnotations: [
            HorizontalRangeAnnotation(
              y1: 5,
              y2: 7,
              color: const Color(0xffEEF3FE),
            ),
          ],
        ),
        extraLinesData: ExtraLinesData(
//         extraLinesOnTop: true,
          horizontalLines: [
            HorizontalLine(
              y: 6,
              color: const Color.fromRGBO(197, 210, 214, 1),
              strokeWidth: 2,
              dashArray: [5, 10],
              label: HorizontalLineLabel(
                show: true,
                alignment: Alignment.topRight,
                padding: const EdgeInsets.only(right: 5, bottom: 5),
                style: const TextStyle(color: Colors.black, fontSize: 9),
                labelResolver: (line) => 'H: ${line.y}',
              ),
            ),
          ],
          verticalLines: [
            VerticalLine(
              x: 5.7,
              color: const Color.fromRGBO(197, 210, 214, 1),
              strokeWidth: 2,
              dashArray: [5, 10],
              label: VerticalLineLabel(
                show: true,
                alignment: Alignment.topRight,
                padding: const EdgeInsets.only(left: 10, top: 5),
                style: const TextStyle(color: Colors.black, fontSize: 9),
                labelResolver: (line) => 'V: ${line.x}',
              ),
            ),
            VerticalLine(
              x: 13.4,
              color: Colors.transparent,
              sizedPicture: sizedPicture,
              label: VerticalLineLabel(
                show: true,
                alignment: Alignment.topRight,
                padding: const EdgeInsets.only(left: 10, top: 5),
                style: const TextStyle(color: Colors.black, fontSize: 9),
                labelResolver: (line) => 'V: ${line.x}',
              ),
            )
          ],
        ),
        minX: 0,
        maxX: _opusCountRange.length.toDouble(),
        maxY: 8,
        minY: 0,
        borderData: FlBorderData(
          show: true,
          border: const Border(
            bottom: BorderSide(color: HYAppTheme.norGrayColor, width: 1),
            left: BorderSide(color: HYAppTheme.norGrayColor, width: 1),
            right: BorderSide(color: Colors.transparent),
            top: BorderSide(color: Colors.transparent),
          ),
        ),
        lineBarsData: [
          LineChartBarData(
            isCurved: true,
            color: HYAppTheme.norTextColors,
            barWidth: 2,
            isStrokeCapRound: true,
            dotData: FlDotData(show: false),
            belowBarData: BarAreaData(show: false),
            spots: _opusCountRange.isEmpty ? [] : getFlSpotList(),
          )
        ],
        lineTouchData: LineTouchData(
          handleBuiltInTouches: true,
          touchTooltipData: LineTouchTooltipData(
            tooltipBgColor: HYAppTheme.norGrayColor,
          ),
        ),
        gridData: FlGridData(show: true),
        titlesData: FlTitlesData(
          bottomTitles: AxisTitles(
            sideTitles: SideTitles(
              showTitles: true,
              reservedSize: 40,
              interval: 1,
              getTitlesWidget: (value, meta) {
                const style = TextStyle(
                  color: HYAppTheme.norGrayColor,
                  fontSize: HYAppTheme.xSmallFontSize,
                );

                Widget text;
                if (_opusCountRange.isEmpty || value.toInt() % 5 != 0) {
                  text = Container();
                } else {
                  String dateString = _opusCountRange[value.toInt()]
                      .date
                      .toString()
                      .substring(5, 10);
                  text = Text(
                    dateString,
                    style: style,
                  );
                }
                return SideTitleWidget(
                  child: text,
                  axisSide: meta.axisSide,
                  space: 10,
                );
              },
            ),
          ),
          rightTitles: AxisTitles(
            sideTitles: SideTitles(showTitles: false),
          ),
          topTitles: AxisTitles(
            sideTitles: SideTitles(showTitles: false),
          ),
          leftTitles: AxisTitles(
            sideTitles: SideTitles(
              getTitlesWidget: (double value, TitleMeta meta) {
                IconData icon;
                Color color;
                Widget iconWidget;
                switch (value.toInt()) {
                  case 2:
                    icon = Icons.wb_sunny;
                    color = const Color(0xFFffab01);
                    iconWidget = Icon(
                      icon,
                      color: color,
                      size: 18,
                    );
                    break;
                  case 4:
                    icon = Icons.wine_bar_sharp;
                    color = const Color(0xFFff0000);
                    iconWidget = Icon(
                      icon,
                      color: color,
                      size: 18,
                    );
                    break;
                  case 6:
                    icon = Icons.watch_later;
                    color = Colors.green;
                    iconWidget = Icon(
                      icon,
                      color: color,
                      size: 18,
                    );
                    break;
                  case 8:
                    icon = Icons.whatshot;
                    color = Colors.deepOrangeAccent;
                    iconWidget = Icon(
                      icon,
                      color: color,
                      size: 18,
                    );
                    break;
                  default:
                    iconWidget = Container();
                }
                return SideTitleWidget(
                  axisSide: meta.axisSide,
                  child: iconWidget,
                );
              },
              showTitles: true,
              interval: 1,
              reservedSize: 30,
            ),
          ),
        ),
      ),
      swapAnimationDuration: Duration(milliseconds: 1000),
    );
  }

  List<FlSpot> getFlSpotList() {
    List<FlSpot> flSpotList = [];
    for (double i = 0; i < 25; i++) {
      double x = i + 1;
      double y = _opusCountRange[i.toInt()].percent2Double;
      flSpotList.add(FlSpot(x, y));
    }
    return flSpotList;
  }
}

class BuildLineChartSample9 extends StatelessWidget {
  final spots = List.generate(101, (i) => (i - 50) / 10)
      .map((x) => FlSpot(x, sin(x)))
      .toList();

  BuildLineChartSample9({Key? key}) : super(key: key);

  Widget bottomTitleWidgets(double value, TitleMeta meta) {
    const style = TextStyle(
      color: Colors.blueGrey,
      fontWeight: FontWeight.bold,
      fontSize: 10,
    );
    return SideTitleWidget(
      axisSide: meta.axisSide,
      space: 16,
      child: Text(meta.formattedValue, style: style),
    );
  }

  Widget leftTitleWidgets(double value, TitleMeta meta) {
    const style = TextStyle(
      color: Colors.blueGrey,
      fontWeight: FontWeight.bold,
      fontSize: 10,
    );
    return SideTitleWidget(
      axisSide: meta.axisSide,
      space: 16,
      child: Text(meta.formattedValue, style: style),
    );
  }

  @override
  Widget build(BuildContext context) {
    return AspectRatio(
      aspectRatio: 1.23,
      child: Container(
        decoration: const BoxDecoration(
          borderRadius: BorderRadius.all(Radius.circular(10)),
          gradient: LinearGradient(
            colors: [
              Color(0x77ef96c5),
              Color(0x77ccfbff),
            ],
            begin: Alignment.bottomCenter,
            end: Alignment.topCenter,
          ),
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            SizedBox(
              height: 37.px,
            ),
            Text(
              'sin函数',
              style: TextStyle(
                color: HYAppTheme.norTextColors,
                fontSize: 16.px,
              ),
              textAlign: TextAlign.center,
            ),
            SizedBox(
              height: 4.px,
            ),
            Text(
              '函数图 (9)',
              style: TextStyle(
                color: Colors.black,
                fontSize: HYAppTheme.smallFontSize,
                fontWeight: FontWeight.bold,
                letterSpacing: 2,
              ),
              textAlign: TextAlign.center,
            ),
            SizedBox(
              height: 37.px,
            ),
            Expanded(
              child: Padding(
                padding: EdgeInsets.only(right: 16.px, left: 6.px),
                child: LineChart(
                  LineChartData(
                    lineTouchData: LineTouchData(
                      touchTooltipData: LineTouchTooltipData(
                          maxContentWidth: 100,
                          tooltipBgColor: Colors.orange,
                          getTooltipItems: (touchedSpots) {
                            return touchedSpots.map((LineBarSpot touchedSpot) {
                              final textStyle = TextStyle(
                                color: touchedSpot.bar.gradient?.colors[0] ??
                                    touchedSpot.bar.color,
                                fontWeight: FontWeight.bold,
                                fontSize: 14,
                              );
                              return LineTooltipItem(
                                  '${touchedSpot.x}, ${touchedSpot.y.toStringAsFixed(2)}',
                                  textStyle);
                            }).toList();
                          }),
                      handleBuiltInTouches: true,
                      getTouchLineStart: (data, index) => 0,
                    ),
                    lineBarsData: [
                      LineChartBarData(
                        color: Colors.black,
                        spots: spots,
                        isCurved: true,
                        isStrokeCapRound: true,
                        barWidth: 3,
                        belowBarData: BarAreaData(
                          show: false,
                        ),
                        dotData: FlDotData(show: false),
                      ),
                    ],
                    minY: -1.5,
                    maxY: 1.5,
                    titlesData: FlTitlesData(
                      leftTitles: AxisTitles(
                        sideTitles: SideTitles(
                          showTitles: true,
                          getTitlesWidget: leftTitleWidgets,
                          reservedSize: 56,
                        ),
                      ),
                      rightTitles: AxisTitles(
                        sideTitles: SideTitles(showTitles: false),
                      ),
                      bottomTitles: AxisTitles(
                        sideTitles: SideTitles(
                          showTitles: true,
                          getTitlesWidget: bottomTitleWidgets,
                          reservedSize: 36,
                        ),
                      ),
                      topTitles: AxisTitles(
                        sideTitles: SideTitles(showTitles: false),
                      ),
                    ),
                    gridData: FlGridData(
                      show: true,
                      drawHorizontalLine: true,
                      drawVerticalLine: true,
                      horizontalInterval: 1.5,
                      verticalInterval: 5,
                      checkToShowHorizontalLine: (value) {
                        return value.toInt() == 0;
                      },
                      checkToShowVerticalLine: (value) {
                        return value.toInt() == 0;
                      },
                    ),
                    borderData: FlBorderData(show: false),
                  ),
                ),
              ),
            ),
            SizedBox(
              height: 10.px,
            ),
          ],
        ),
      ),
    );
  }
}

class BuildLineChartSample10 extends StatefulWidget {
  const BuildLineChartSample10({Key? key}) : super(key: key);

  @override
  _BuildLineChartSample10State createState() => _BuildLineChartSample10State();
}

class _BuildLineChartSample10State extends State<BuildLineChartSample10> {
  final Color sinColor = Colors.redAccent;
  final Color cosColor = Colors.blueAccent;

  final limitCount = 100;
  final sinPoints = <FlSpot>[];
  final cosPoints = <FlSpot>[];

  double xValue = 0;
  double step = 0.05;

  late Timer timer;

  @override
  void initState() {
    super.initState();
    timer = Timer.periodic(const Duration(milliseconds: 40), (timer) {
      while (sinPoints.length > limitCount) {
        sinPoints.removeAt(0);
        cosPoints.removeAt(0);
      }
      setState(() {
        sinPoints.add(FlSpot(xValue, math.sin(xValue)));
        cosPoints.add(FlSpot(xValue, math.cos(xValue)));
      });
      xValue += step;
    });
  }

  @override
  Widget build(BuildContext context) {
    return AspectRatio(
      aspectRatio: 1.0,
      child: Container(
        decoration: const BoxDecoration(
          borderRadius: BorderRadius.all(Radius.circular(10)),
          gradient: LinearGradient(
            colors: [
              Color(0x77ef96c5),
              Color(0x77ccfbff),
            ],
            begin: Alignment.bottomCenter,
            end: Alignment.topCenter,
          ),
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            SizedBox(
              height: 37.px,
            ),
            Text(
              'sin函数和cos函数',
              style: TextStyle(
                color: HYAppTheme.norTextColors,
                fontSize: 16.px,
              ),
              textAlign: TextAlign.center,
            ),
            SizedBox(
              height: 4.px,
            ),
            Text(
              '函数图 (10)',
              style: TextStyle(
                color: Colors.black,
                fontSize: HYAppTheme.smallFontSize,
                fontWeight: FontWeight.bold,
                letterSpacing: 2,
              ),
              textAlign: TextAlign.center,
            ),
            SizedBox(
              height: 10.px,
            ),
            Expanded(
              child: Padding(
                padding: EdgeInsets.only(right: 16.px, left: 6.px),
                child: cosPoints.isNotEmpty
                    ? Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Text(
                            ///toStringAsFixed保留几位小数
                            'x: ${xValue.toStringAsFixed(1)}',
                            style: const TextStyle(
                              color: Colors.black,
                              fontSize: 18,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                          Text(
                            'sin: ${sinPoints.last.y.toStringAsFixed(1)}',
                            style: TextStyle(
                              color: sinColor,
                              fontSize: 18,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                          Text(
                            'cos: ${cosPoints.last.y.toStringAsFixed(1)}',
                            style: TextStyle(
                              color: cosColor,
                              fontSize: 18,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                          const SizedBox(
                            height: 12,
                          ),
                          SizedBox(
                            width: 200,
                            height: 100,
                            child: LineChart(
                              LineChartData(
                                minY: -1,
                                maxY: 1,
                                minX: sinPoints.first.x,
                                maxX: sinPoints.last.x,
                                lineTouchData: LineTouchData(enabled: false),
                                clipData: FlClipData.all(),
                                gridData: FlGridData(
                                  show: true,
                                  drawVerticalLine: false,
                                ),
                                lineBarsData: [
                                  sinLine(sinPoints),
                                  cosLine(cosPoints),
                                ],
                                titlesData: FlTitlesData(
                                  show: false,
                                ),
                              ),
                            ),
                          )
                        ],
                      )
                    : Container(),
              ),
            ),
            SizedBox(
              height: 10.px,
            ),
          ],
        ),
      ),
    );
  }

  LineChartBarData sinLine(List<FlSpot> points) {
    return LineChartBarData(
      spots: points,
      dotData: FlDotData(
        show: false,
      ),
      gradient: LinearGradient(
          colors: [sinColor.withOpacity(0), sinColor],
          begin: Alignment.centerLeft,
          end: Alignment.centerRight,
          stops: const [0.1, 1.0]),
      barWidth: 4,
      isCurved: false,
    );
  }

  LineChartBarData cosLine(List<FlSpot> points) {
    return LineChartBarData(
      spots: points,
      dotData: FlDotData(
        show: false,
      ),
      gradient: LinearGradient(
          colors: [sinColor.withOpacity(0), sinColor],
          begin: Alignment.centerLeft,
          end: Alignment.centerRight,
          stops: const [0.1, 1.0]),
      barWidth: 4,
      isCurved: false,
    );
  }

  @override
  void dispose() {
    timer.cancel();
    super.dispose();
  }
}
